package com.lineage.server.datatables;

import com.lineage.DatabaseFactory;
import com.lineage.server.IdFactoryNpc;
import com.lineage.server.model.Instance.L1DoorInstance;
import com.lineage.server.model.L1Object;
import com.lineage.server.templates.L1Npc;
import com.lineage.server.utils.PerformanceTimer;
import com.lineage.server.utils.SQLUtil;
import com.lineage.server.world.World;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class DoorSpawnTable {
  private static final Log _log = LogFactory.getLog(DoorSpawnTable.class);
  
  private static DoorSpawnTable _instance;
  
  private static final ArrayList<L1DoorInstance> _doorList = new ArrayList<>();
  
  public static DoorSpawnTable get() {
    if (_instance == null)
      _instance = new DoorSpawnTable(); 
    return _instance;
  }
  
  public void load() {
    PerformanceTimer timer = new PerformanceTimer();
    int i = 0;
    Connection con = null;
    PreparedStatement pstm = null;
    ResultSet rs = null;
    try {
      con = DatabaseFactory.get().getConnection();
      pstm = con.prepareStatement("SELECT * FROM `spawnlist_door`");
      rs = pstm.executeQuery();
      while (rs.next()) {
        i++;
        L1Npc l1npc = NpcTable.get().getTemplate(81158);
        if (l1npc != null) {
          int id = rs.getInt("id");
          if (id >= 808 && id <= 812)
            continue; 
          L1DoorInstance door = (L1DoorInstance)NpcTable.get().newNpcInstance(l1npc);
          door.setId(IdFactoryNpc.get().nextId());
          door.setDoorId(id);
          door.setGfxId(rs.getInt("gfxid"));
          int x = rs.getInt("locx");
          int y = rs.getInt("locy");
          door.setX(x);
          door.setY(y);
          door.setMap(rs.getShort("mapid"));
          door.setHomeX(x);
          door.setHomeY(y);
          door.setDirection(rs.getInt("direction"));
          door.setLeftEdgeLocation(rs.getInt("left_edge_location"));
          door.setRightEdgeLocation(rs.getInt("right_edge_location"));
          int hp = rs.getInt("hp");
          door.setMaxHp(hp);
          door.setCurrentHp(hp);
          door.setKeeperId(rs.getInt("keeper"));
          World.get().storeObject((L1Object)door);
          World.get().addVisibleObject((L1Object)door);
          _doorList.add(door);
        } 
      } 
    } catch (SQLException e) {
      _log.error(e.getLocalizedMessage(), e);
    } catch (SecurityException e2) {
      _log.error(e2.getLocalizedMessage(), e2);
    } catch (IllegalArgumentException e3) {
      _log.error(e3.getLocalizedMessage(), e3);
    } finally {
      SQLUtil.close(rs);
      SQLUtil.close(pstm);
      SQLUtil.close(con);
    } 
    _log.info("载入门资料数量: " + i + "(" + timer.get() + "ms)");
  }
  
  public void removeDoor(L1DoorInstance door) {
    _doorList.remove(door);
  }
  
  public L1DoorInstance[] getDoorList() {
    return _doorList.<L1DoorInstance>toArray(new L1DoorInstance[_doorList.size()]);
  }
  
  public L1DoorInstance spawnDoor(int doorId, int gfxId, int locx, int locy, short mapid, int hp, int keeper, boolean isopening, int left_edge_location, int right_edge_location) {
    return spawnDoor(doorId, gfxId, locx, locy, mapid, hp, keeper, isopening, left_edge_location, 
        right_edge_location, 0);
  }
  
  public L1DoorInstance spawnDoor(int doorId, int gfxId, int locx, int locy, short mapid, int hp, int keeper, boolean isopening, int left_edge_location, int right_edge_location, int direction) {
    Iterator<L1DoorInstance> iterator = _doorList.iterator();
    while (iterator.hasNext()) {
      L1DoorInstance temp = iterator.next();
      if (temp.getMapId() == mapid && temp.getHomeX() == locx && temp.getHomeY() == locy)
        return temp; 
    } 
    L1Npc l1npc = NpcTable.get().getTemplate(81158);
    L1DoorInstance door = (L1DoorInstance)NpcTable.get().newNpcInstance(l1npc);
    door.setId(IdFactoryNpc.get().nextId());
    door.setDoorId(doorId);
    door.setGfxId(gfxId);
    door.setX(locx);
    door.setY(locy);
    door.setMap(mapid);
    door.setHomeX(locx);
    door.setHomeY(locy);
    door.setDirection(direction);
    door.setLeftEdgeLocation(left_edge_location);
    door.setRightEdgeLocation(right_edge_location);
    door.setMaxHp(hp);
    door.setCurrentHp(hp);
    door.setKeeperId(keeper);
    World.get().storeObject((L1Object)door);
    World.get().addVisibleObject((L1Object)door);
    _doorList.add(door);
    return door;
  }
  
  public void addDoor(L1DoorInstance door) {
    _doorList.add(door);
  }
}
